import { reactive, ref, Ref, unref } from 'vue';
import { isNil, isNull, merge } from 'lodash-es';
import { DynamicProps } from '#/utils';
import { BasicTableProps, TableActionType, useTable } from '@/components/Table';
import { ColEx } from '@/components/Form/src/types';
import { FormActionType } from '@/components/Form';
import { useMessage } from '@/hooks/web/useMessage';
import { useMethods } from '@/hooks/system/useMethods';

import { ExcelConfigType } from '@/utils/props';

const { handleExportXls, handleImportXls } = useMethods();

// 定义表格所需参数
type TableProps = Partial<DynamicProps<BasicTableProps>>;
type UseTableMethod = TableActionType & {
  getForm: () => FormActionType;
};
export interface IRowSelection {
  rowSelection: any;
  selectedRows: Ref<Recordable[]>;
  selectedRowKeys: Ref<any[]>;
}
export interface IConfigExcel {
  onExportXls: () => void;
  onImportXls: (file) => void;
  loadingRef: Ref<boolean>;
}
export interface ITableActionType extends TableActionType {
  getForm: () => FormActionType;
}
export interface ITableInstance {
  (instance: TableActionType, formInstance: UseTableMethod): void;
}

/**
 * useListTable 列表页面标准表格参数
 *
 * @param tableProps 表格参数
 * @param excelConfig excel导入导出参数
 */

export function useListTable(
  tableProps: TableProps,
  excelConfig?: ExcelConfigType,
): [ITableInstance, ITableActionType, IRowSelection, IConfigExcel] {
  // 自适应列配置
  const adaptiveColProps: Partial<ColEx> = {
    xs: 24, // <576px
    sm: 12, // ≥576px
    md: 12, // ≥768px
    lg: 8, // ≥992px
    xl: 8, // ≥1200px
    xxl: 6, // ≥1600px
  };

  const defaultTableProps: TableProps = {
    rowKey: 'id',
    // 使用查询条件区域
    useSearchForm: true,
    // 查询条件区域配置
    formConfig: {
      // 紧凑模式
      compact: true,
      // label默认宽度
      // labelWidth: 120,
      // 按下回车后自动提交
      autoSubmitOnEnter: true,
      // 默认 row 配置
      rowProps: { gutter: 8 },
      // 默认 col 配置
      baseColProps: {
        ...adaptiveColProps,
      },
      labelCol: {
        xs: 24,
        sm: 8,
        md: 6,
        lg: 8,
        xl: 6,
        xxl: 6,
      },
      wrapperCol: {},
      // 是否显示 展开/收起 按钮
      showAdvancedButton: true,
      // 超过指定列数默认折叠
      //autoAdvancedCol: 3,

      // 操作按钮配置
      actionColOptions: {
        ...adaptiveColProps,
        style: { textAlign: 'left' },
      },
      //autocomplete: 'off',
    },
    size: 'small',
    // 斑马纹
    striped: false,
    // 是否可以自适应高度
    canResize: true,
    // 表格最小高度
    //minHeight: 500,
    // 点击行选中
    clickToRowSelect: false,
    // 是否显示边框
    bordered: true,
    // 是否显示序号列
    showIndexColumn: false,
    // 显示表格设置
    showTableSetting: true,
    // 表格全屏设置
    tableSetting: {
      fullScreen: false,
    },

    // 操作列
    actionColumn: {
      width: 150,
      title: '操作',
      //是否锁定操作列取值 right ,left,false
      fixed: 'right',
      dataIndex: 'action',
    },
    afterFetch: (rows) => {
      if (isNil(rows) || isNull(rows)) {
        return [];
      }
      return rows;
    },
  };
  // 合并用户个性化配置
  if (tableProps) {
    // merge 方法可深度合并对象
    merge(defaultTableProps, tableProps);
  }

  // 发送请求之前调用的方法
  function beforeFetch(params) {
    // 默认以 createTime 降序排序
    return Object.assign({ column: 'createTime', order: 'desc' }, params);
  }

  // 合并方法
  Object.assign(defaultTableProps, { beforeFetch });
  if (typeof tableProps.beforeFetch === 'function') {
    defaultTableProps.beforeFetch = function (params) {
      //params = beforeFetch(params);
      // @ts-ignore
      tableProps.beforeFetch(params);
      return params;
    };
  }

  // 当前选择的行
  const selectedRowKeys = ref<any[]>([]);
  // 选择的行记录
  const selectedRows = ref<Recordable[]>([]);

  // 表格选择列配置
  const rowSelection: any = tableProps?.rowSelection ?? {};
  const defaultRowSelection = reactive({
    ...rowSelection,
    type: rowSelection.type ?? 'checkbox',
    // 选择列宽度，默认 50
    columnWidth: rowSelection.columnWidth ?? 50,
    selectedRows: selectedRows,
    selectedRowKeys: selectedRowKeys,
    onChange(...args) {
      selectedRowKeys.value = args[0];
      selectedRows.value = args[1];
      if (typeof rowSelection.onChange === 'function') {
        rowSelection.onChange(...args);
      }
    },
  });

  const $message = useMessage();
  delete defaultTableProps.rowSelection;
  const tableContext = useTable(defaultTableProps);
  const [, { getForm, reload }] = tableContext;
  async function onExportXls() {
    const { url, name, params } = excelConfig?.exportConfig ?? {};
    const realUrl = typeof url === 'function' ? url() : url;
    if (realUrl) {
      const title = typeof name === 'function' ? name() : name;

      let paramsForm: any = {};
      try {
        paramsForm = await getForm().getFieldsValue();
      } catch (e) {
        console.error(e);
      }
      if (params) {
        Object.keys(params).map((k) => {
          const temp = (params as object)[k];
          if (temp) {
            paramsForm[k] = unref(temp);
          }
        });
      }

      if (selectedRowKeys.value && selectedRowKeys.value.length > 0) {
        paramsForm['selections'] = selectedRowKeys.value.join(',');
      }
      return handleExportXls(title as string, realUrl, paramsForm);
    } else {
      $message.createMessage.warn('没有传递 exportConfig.url 参数');
      return Promise.reject();
    }
  }
  const loadingRef = ref<boolean>(false);

  function onImportXls(file) {
    const { url, success } = excelConfig?.importConfig ?? {};

    const realUrl = typeof url === 'function' ? url() : url;
    if (realUrl) {
      loadingRef.value = true;
      return handleImportXls(file, realUrl, success || reload)
        .then(() => {
          loadingRef.value = false;
          return Promise.resolve();
        })
        .catch((e) => {
          loadingRef.value = false;
          return Promise.reject(e);
        });
    } else {
      $message.createMessage.warn('没有传递 importConfig.url 参数');
      return Promise.reject();
    }
  }
  return [
    ...tableContext,
    {
      selectedRows,
      selectedRowKeys,
      rowSelection: defaultRowSelection,
    },
    {
      onExportXls,
      onImportXls,
      loadingRef,
    },
  ];
}
